package org.jeecg.modules.system.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信小程序用户接口
 *
 * @author dongw
 */
@RestController
@AllArgsConstructor
@Slf4j
@RequestMapping("/wx/user")
public class WxMaUserController {
    private final WxMaService wxMaService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ISysUserService userService;

    /**
     * 登陆接口
     */
    @GetMapping("/login/{appid}")
    public Result login(@PathVariable String appid, String code, HttpServletRequest request) {
        if (StringUtils.isBlank(code)) {
            return Result.error("empty jscode");
        }

        if (!wxMaService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }

        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
            log.info(session.getSessionKey());
            log.info(session.getOpenid());
            JSONObject respData = new JSONObject();
            SysUser userByName = userService.getOne(Wrappers.<SysUser>lambdaQuery()
                    .eq(SysUser::getUsername, session.getOpenid())
            );
            if (null == userByName) {
                try {
                    SysUser user = new SysUser();
                    user.setCreateTime(new Date());//设置创建时间
                    String salt = oConvertUtils.randomGen(8);
                    user.setSalt(salt);
                    user.setUsername(session.getOpenid());
                    String passwordEncode = PasswordUtil.encrypt(session.getOpenid(), session.getOpenid(), salt);
                    user.setPassword(passwordEncode);
                    user.setStatus(1);
                    user.setDelFlag(CommonConstant.DEL_FLAG_0);
                    user.setOrgCode(null);
                    userService.save(user);
                    respData.put("phone", null);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            } else {
                respData.put("phone", userByName.getPhone());
                respData.put("isAdmin", userByName.getClientId());
            }
            //1.生成token
            String token = JwtUtil.sign(session.getOpenid(), session.getOpenid());
            // 设置token缓存有效时间
            redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
            redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 10 / 1000);
            respData.put("openid", session.getOpenid());
            respData.put("sessionKey", session.getSessionKey());
            respData.put("token", token);
            return Result.OK(respData);
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            return Result.error(e.getMessage());
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
    }

    @GetMapping("/getPhone/{code}")
    public Result getPhone(@PathVariable String code, String openId) {
        try {//  WxUserInfo userInfo = WxOpenApi.getUserInfo();
            Object o = redisUtil.get("wx:ma:accessToken");
            String accessToken = null;
            if (null == o) {
                accessToken = wxMaService.getAccessToken();
                redisUtil.set("wx:ma:accessToken", accessToken, 1800);
            } else {
                accessToken = o.toString();
            }
            log.info("accessToken:{}", accessToken);
            Map<String, String> params = new HashMap<>();
            params.put("code", code);
            String result2 = HttpRequest.post("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken)
                    .body(JSON.toJSONString(params))
                    .execute().body();
            JSONObject response = JSONObject.parseObject(result2);
            if (response.getInteger("errcode") == 0) {
//                String phoneNumber = response.getJSONObject("phone_info").getString("phoneNumber");
//                String countryCode = response.getJSONObject("phone_info").getString("countryCode");
                userService.update(Wrappers.<SysUser>lambdaUpdate()
                        .eq(SysUser::getUsername, openId)
                        .set(SysUser::getPhone, response.getJSONObject("phone_info").getString("phoneNumber"))
                );
                SysUser userByName = userService.getUserByName(openId);
                JSONObject resData = new JSONObject();
                resData.put("phone",response.getJSONObject("phone_info").getString("phoneNumber"));
                resData.put("isAdmin",userByName.getClientId());
                return Result.OK(resData);
            } else {
                return Result.error(response.getString("errmsg"));
            }
        } catch (WxErrorException e) {
            return Result.error("手机号码获取失败");
        }
    }

}
